package com.lubase.metadata.tabletrigger;

import com.lubase.model.DbEntity;
import com.lubase.model.DbTable;
import com.lubase.model.EDBEntityState;
import com.lubase.orm.QueryOption;
import com.lubase.orm.TableFilter;
import com.lubase.orm.exception.WarnCommonException;
import com.lubase.orm.extend.ITableTrigger;
import com.lubase.model.DbCollection;
import com.lubase.orm.operate.EOperateMode;
import com.lubase.orm.service.DataAccess;
import com.lubase.orm.util.TableFilterWrapper;
import com.lubase.orm.util.TypeConverterUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MsDatabaseInfoTrigger implements ITableTrigger {

    /**
     * 1: 生产主库  2：生产备库  3：测试环境
     */
    @Value("${custom.metadata-database-environment}")
    private String metadataDatabaseEnvironment;
    @Autowired
    DataAccess dataAccess;

    @Override
    public Boolean beforeValidate(DbTable tableInfo, DbEntity entity, Boolean isServer) throws Exception {
        // 如果是删除的话，禁止删除读取元数据环境的数据
        if (entity.getDataState().equals(EDBEntityState.Deleted)) {
            QueryOption queryOption = new QueryOption("ms_database_info");
            queryOption.setFixField("env_info,lake_database_code");
            queryOption.setTableFilter(new TableFilter("id", entity.getId(), EOperateMode.Equals));
            DbCollection coll = dataAccess.queryAllData(queryOption);
            if (!coll.getData().isEmpty()) {
                String envInfo = TypeConverterUtils.object2String(coll.getData().get(0).get("env_info"), "");
                String lakeDatabaseCode = TypeConverterUtils.object2String(coll.getData().get(0).get("lake_database_code"), "");
                if (envInfo.equals(metadataDatabaseEnvironment)) {
                    throw new WarnCommonException("此环境用于读取元数据，禁止删除");
                }
                if (StringUtils.isNotEmpty(lakeDatabaseCode)) {
                    throw new WarnCommonException("此环境已关联中台数据库，禁止删除");
                }
            }
        } else if (entity.getDataState().equals(EDBEntityState.Added)) {
            String envInfo = entity.get("env_info").toString();
            // 环境信息不能重复
            QueryOption queryOption = new QueryOption("ms_database_info");
            queryOption.setFixField("id");
            TableFilterWrapper filterWrapper = TableFilterWrapper.and();
            filterWrapper.eq("env_info", envInfo).eq("ms_database_id", entity.get("ms_database_id"));
            queryOption.setTableFilter(filterWrapper.build());
            if (!dataAccess.query(queryOption).getData().isEmpty()) {
                throw new WarnCommonException("环境信息不能重复");
            }
        }
        return true;
    }

    @Override
    public void afterUpdate(DbTable tableInfo, DbEntity entity, Boolean isServer) throws Exception {
        if (entity.getDataState().equals(EDBEntityState.Added) || entity.getDataState().equals(EDBEntityState.Modified)) {
            String databaseId = entity.get("ms_database_id").toString();
            // 将数据库连接信息同步到数据源表
            QueryOption queryOption = new QueryOption("ms_database");
            queryOption.setTableFilter(new TableFilter("id", databaseId));
            DbCollection coll = dataAccess.queryAllData(queryOption);
            if (!coll.getData().isEmpty()) {
                DbEntity dbEntity = coll.getData().get(0);
                dbEntity.put("database_code", entity.get("database_code"));
                dbEntity.put("host", entity.get("host"));
                dbEntity.setState(EDBEntityState.Modified);
                dataAccess.update(coll);
            }
        }
    }

    @Override
    public String getTriggerTableCode() {
        return "ms_database_info";
    }

    @Override
    public String getTriggerName() {
        return "ms_database_info";
    }

    @Override
    public Boolean isAdd() {
        return true;
    }

    @Override
    public Boolean isEdit() {
        return true;
    }

    @Override
    public Boolean isDelete() {
        return true;
    }
}
